package com.zmzncs.lmtc.common.util;

import com.alibaba.fastjson.JSONObject;
import com.zmzncs.lmtc.common.pojo.constant.charge.Constant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class WeChatUtil {


    public static String code ="SMS_147915193";
    public static String xcxAppId ="wx3069280b94304887";
    public static String xcxAppSecret ="ad4f3f496602aa8721342d437a045cf2";
    public static String xcxMchId = "1515187001";
    public static String appApiKey = "ZMzncs20FZjs17yxgs3HBjk20GC09zx8";
    private static final String KEY_ALGORITHM = "AES";
    private static final String ALGORITHM_STR = "AES/CBC/PKCS7Padding";
    private static Key key;
    private static Cipher cipher;
    private static String GET_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";

    //基础获得TOKEN
    public static String getAccessToken(String appId, String secret) {
        Map<String, String> map = new HashMap<>();
        map.put("grant_type", "client_credential");
        map.put("appid", appId);
        map.put("secret", secret);
        String ret = HttpUtil.requestGet(GET_TOKEN_URL, map, null);
        return ret;
    }

    /**
     * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
     *
     * @return boolean
     */
    public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (!"sign".equals(k) && null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + API_KEY);
        //算出摘要
        String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();
        String tenpaySign = ((String) packageParams.get("sign")).toLowerCase();
        return tenpaySign.equals(mysign);
    }

    /**
     * @Description：sign签名 编码格式
     */
    public static String createSign(SortedMap<Object, Object> packageParams, String API_KEY) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + API_KEY);
        String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        return sign;
    }

    /**
     * @param parameters 请求参数
     * @return
     * @author
     * @date 2016-4-22
     * @Description：将请求参数转换为xml格式的string
     */
    public static String getRequestXml(SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
            } else {
                sb.append("<" + k + ">" + v + "</" + k + ">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }

    /**
     * 取出一个指定长度大小的随机正整数.
     *
     * @param length int 设定所取出随机数的长度。length小于11
     * @return int 返回生成的随机数。
     */
    public static int buildRandom(int length) {
        int num = 1;
        double random = Math.random();
        if (random < 0.1) {
            random = random + 0.1;
        }
        for (int i = 0; i < length; i++) {
            num = num * 10;
        }
        return (int) ((random * num));
    }

    /**
     * 获取当前时间 微信随机字符串
     *
     * @return String
     */
    static public String nonceString() {
        String currTime = String.format("%d", System.currentTimeMillis() / 1000);
        Random random = new Random();
        int num = (int) (random.nextDouble() * (1000000 - 100000) + 100000);
        String code = String.format("%06d", num);
        String nonce_str = currTime.substring(2) + code;
        return nonce_str;
    }

    /**
     * 返回微信秒为单位时间戳
     *
     * @return String
     */
    static public String timeStamp() {
        String currTime = String.format("%d", (long) System.currentTimeMillis() / 1000);
        return currTime;
    }

    /**
     * 得到本地机器的IP
     */
    public static String getHostIp() {
        String ip = "";
        try {
            ip = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return ip;
    }

    /**
     * @param
     * @return
     * @author
     * @date 2016-4-22
     * @Description：sign签名 JS_SDK使用权限签名算法
     */
    public static String signature(SortedMap<Object, Object> packageParams) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        //最后一个&截掉
        String s = sb.substring(0, sb.lastIndexOf("&"));
        String sign = getSha1(s);
        return sign;
    }

    public static String getSha1(String str) {
        if (str == null || str.length() == 0) {
            return null;
        }
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));

            byte[] md = mdTemp.digest();
            int j = md.length;
            char buf[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(buf);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 微信支付回调成功字符串
     *
     * @return
     */
    public static String wxpayCallbackResult(boolean success) {
        String status = success ? "SUCCESS" : "FAIL";
        return "<xml><return_code><![CDATA[" + status + "]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    }

    /**
     * 解析微信回调
     *
     * @param request
     * @return
     */
    public static String parseCallback(HttpServletRequest request) {
        StringBuffer sb = new StringBuffer();
        InputStream is = null;
        try {
            is = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (Exception e) {
            log.error(" callback1 param parse error", e);
        } finally {
            try {
                is.close();
            } catch (Exception e) {
                log.error("close io stream error", e);
            }
        }
        return sb.toString();
    }


    /**
     * 生成iv
     */
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
        // iv 为一个 16 字节的数组，这里采用和 iOS 端一样的构造方法，数据全为0
        // Arrays.fill(iv, (byte) 0x00);
        AlgorithmParameters params = AlgorithmParameters.getInstance(Constant.AES);
        params.init(new IvParameterSpec(iv));
        return params;
    }


    private static String REGEX_CHINESE = "[\u4e00-\u9fa5]";// 中文正则

    public static String getOrderNo(String carNo) {
        if (StringUtils.isBlank(carNo)) {
            return getRannumNo();
        }
        // 去除中文
        Pattern pat = Pattern.compile(REGEX_CHINESE);
        Matcher mat = pat.matcher(carNo);
        String cNo = mat.replaceAll("");
        return cNo + "_" + getRannumNo();
    }

    public static String getRannumNo() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date();
        String str = simpleDateFormat.format(date);
        Random random = new Random();
        int rannum = (int) (random.nextDouble() * 5);// 获取5位随机数
        return str + rannum;// 当前时间 + 系统5随机生成位数
    }


    /**
     * 查询历史订单
     *
     * @param openid
     * @param orderCode 订单号
     */
    public static Map<String, Object> queryOrder(String openid, String orderCode) {
        HashMap<String, Object> objMap = new HashMap<String, Object>();
        objMap.put("appid", Constant.xcxAppId); //  微信分配的小程序ID
        objMap.put("mch_id", Constant.xcxMchId);   //  微信支付分配的商户号
        objMap.put("out_trade_no", orderCode);    //  商户系统内部订单号
        objMap.put("nonce_str", WeChatUtil.nonceString()); //  随机字符串，长度要求在32位以内。
        SortedMap<Object, Object> packageParams = new TreeMap(objMap);
        packageParams.put("sign", WeChatUtil.createSign(packageParams, Constant.appApiKey));    //  签名值
        String requestXML = WeChatUtil.getRequestXml(packageParams);
        String UNI_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
        String respBody = HttpUtil.requestPostBody(UNI_URL, requestXML, null);

        log.info("历史订单：{}", respBody);

        return null;
    }


    /**
     * 微信支付接口
     *
     * @param openid
     * @param totalFee  金额
     * @param orderCode 订单号
     * @param attach    附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。
     * @param desc      商品描述
     */
    public static Map<String, Object> wxPay(String openid, String notifyUrl, BigDecimal totalFee, String orderCode, String attach, String desc) {
        String appid = Constant.xcxAppId;
        String mch_id = Constant.xcxMchId;

        String apikey = Constant.appApiKey;

        //元转分
        int newTotalFee = (totalFee.multiply(new BigDecimal(100))).intValue();

        HashMap<String, Object> objMap = new HashMap<String, Object>();
        objMap.put("appid", appid); //  微信分配的小程序ID
        objMap.put("mch_id", mch_id);   //  微信支付分配的商户号
        objMap.put("openid", openid);   //  trade_type=JSAPI，此参数必传，用户在商户appid下的唯一标识
        objMap.put("body", desc);   //  商品简单描述
        objMap.put("out_trade_no", orderCode);    //  商户系统内部订单号
        objMap.put("total_fee", String.valueOf(newTotalFee));   //  订单总金额，单位为分
        objMap.put("notify_url", notifyUrl);   //  支付结果通知的回调地址
        objMap.put("attach", attach);   //  附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。
        objMap.put("spbill_create_ip", WeChatUtil.getHostIp()); //  调用微信支付API的机器IP
        objMap.put("trade_type", "JSAPI");  //  小程序取值：JSAPI
        objMap.put("nonce_str", WeChatUtil.nonceString()); //  随机字符串，长度要求在32位以内。
        SortedMap<Object, Object> packageParams = new TreeMap(objMap);
        packageParams.put("sign", WeChatUtil.createSign(packageParams, apikey));    //  签名值
        String requestXML = WeChatUtil.getRequestXml(packageParams);
        String UNI_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        String respBody = HttpUtil.requestPostBody(UNI_URL, requestXML, null);

        Map<String, Object> respMap = null;
        if (StringUtils.isEmpty(respBody)) {
            ExceptionUtil.businessException("支付失败");
        }
        respMap = XmlUtil.xmlBody2map(respBody, "xml");

        String returnCode = (String) respMap.get("return_code");
        if ("SUCCESS".equals(returnCode)) {
            //  支付失败
            if (!respMap.get("result_code").equals("SUCCESS")) {
                ExceptionUtil.businessException(respMap.get("err_code_des").toString());
            }

            String prepayId = (String) respMap.get("prepay_id");
            SortedMap<Object, Object> obj2 = new TreeMap();

            String timeStamp = WeChatUtil.timeStamp();
            obj2.put("appId", appid);   //  调用接口提交的小程序ID
            obj2.put("nonceStr", WeChatUtil.nonceString()); //  微信返回的随机字符串
            obj2.put("package", "prepay_id=" + prepayId);   //  微信生成的预支付会话标识，用于后续接口调用中使用，该值有效期为2小时
            obj2.put("signType", "MD5");    //  签名算法
            obj2.put("timeStamp", timeStamp);
            String sign2 = WeChatUtil.createSign(obj2, apikey);

            HashMap<String, Object> returnMap = new HashMap();
            returnMap.put("timeStamp", timeStamp);
            returnMap.put("package", obj2.get("package"));
            returnMap.put("nonceStr", obj2.get("nonceStr"));
            returnMap.put("signType", obj2.get("signType"));
            returnMap.put("orderCode", orderCode);
            returnMap.put("paySign", sign2);

            return returnMap;
        } else {
            ExceptionUtil.businessException(respMap.toString());
        }
        return null;
    }


    /**
     * 微信支付接口
     *
     * @param orderCode 订单号
     */
    public static Map<String, Object> wxOrderquery(String orderCode) {
        String appid = Constant.xcxAppId;
        String mch_id = Constant.xcxMchId;
        String apikey = Constant.appApiKey;

        HashMap<String, Object> objMap = new HashMap<String, Object>();
        objMap.put("appid", appid); //  微信分配的小程序ID
        objMap.put("mch_id", mch_id);   //  微信支付分配的商户号
        objMap.put("out_trade_no", orderCode);    //  商户系统内部订单号
        objMap.put("nonce_str", WeChatUtil.nonceString()); //  随机字符串，长度要求在32位以内。s
        objMap.put("sign_type", "MD5");  //  默认：MD5
        SortedMap<Object, Object> packageParams = new TreeMap(objMap);
        packageParams.put("sign", WeChatUtil.createSign(packageParams, apikey));    //  签名值
        String requestXML = WeChatUtil.getRequestXml(packageParams);
        String UNI_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
        String respBody = HttpUtil.requestPostBody(UNI_URL, requestXML, null);

        Map<String, Object> respMap = XmlUtil.xmlBody2map(respBody, "xml");

        return respMap;
    }


    /**
     * 获取微信用户openid
     */
    public static Map<String, Object> getOpenId(String code) {
        if (StringUtils.isBlank(code)) {
            return null;
        }
        String appid = Constant.xcxAppId;
        String secret = Constant.xcxAppSecret;
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
        String respBody1 = HttpUtil.requestGet(url, null, null);
        JSONObject jsStr = JSONObject.parseObject(respBody1);
        String openId = String.valueOf(jsStr.get("openid"));
        String session_key = String.valueOf(jsStr.get("session_key"));
        Map<String, Object> map = new HashMap<>();
        map.put("openId", openId);
        map.put("session_key", session_key);
        return map;
    }

    /**
     * 解析电话号码
     *
     * @param encryptedData
     * @param iv
     * @return
     */
    public static JSONObject getPhoneNumber(String code, String encryptedData, String iv) {
        String session_key1 = "";
        Map map = WeChatUtil.getOpenId(code);
        if (map != null && map.get("session_key") != null) {
            session_key1 = map.get("session_key").toString();
        }
        String encryptedData1 = encryptedData.replace(" ", "+");
        String iv1 = iv.replace(" ", "+");

        byte[] dataByte = Base64.decodeBase64(encryptedData1);
        byte[] keyByte = Base64.decodeBase64(session_key1);
        byte[] ivByte = Base64.decodeBase64(iv1);
        try {
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
//            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return JSONObject.parseObject(result);
            }
        } catch (Exception e) {
            log.error("获取手机号失败", e);
        }
        return null;
    }


    /**
     * 微信退款申请
     *
     * @param refundNo 退款编号
     * @param totalFee 退款订单总金额
     * @param refundFee 退款金额
     * @param orderCode 订单号
     * @param refundDesc 退款备注
     * @return
     */
    public static Map<String, Object> refund(String refundNo, BigDecimal totalFee, BigDecimal refundFee, String orderCode, String refundDesc) {
        String appid = Constant.xcxAppId;
        String mch_id = Constant.xcxMchId;
        String apikey = Constant.appApiKey;

        //元转分
        //订单金额
        int newTotalFee = (totalFee.multiply(new BigDecimal(100))).intValue();
        //退款金额
        int newRefundFee = (refundFee.multiply(new BigDecimal(100))).intValue();

        HashMap<String, Object> objMap = new HashMap<String, Object>();
        objMap.put("appid", appid);    //微信分配的小程序ID
        objMap.put("mch_id", mch_id);  //微信支付分配的商户号
        objMap.put("nonce_str", WeChatUtil.nonceString());  //随机字符串，长度要求在32位以内
        objMap.put("out_trade_no", orderCode);  //商户系统内部订单号
        objMap.put("out_refund_no", refundNo);  //商户退款单号
        objMap.put("total_fee", String.valueOf(newTotalFee));   //订单总金额，单位为分
        objMap.put("refund_fee", String.valueOf(newRefundFee)); //退款金额，单位为分
        objMap.put("refund_desc", refundDesc);  //退款原因
        SortedMap<Object, Object> packageParams = new TreeMap(objMap);
        packageParams.put("sign", WeChatUtil.createSign(packageParams, apikey));   //签名值
        String requestXML = WeChatUtil.getRequestXml(packageParams);
        String refundUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";

        //发起退款
        String respBody = null;
        try {
            respBody = doRefund(mch_id,refundUrl,requestXML);
        } catch (Exception e) {
            e.printStackTrace();
        }

        log.info("返回信息：" + respBody);
        if (StringUtils.isEmpty(respBody)) {
            ExceptionUtil.businessException("支付失败");
        }

        Map<String, Object> respMap = XmlUtil.xmlBody2map(respBody, "xml");

        return respMap;
    }

    /**
     * 验证微信支付证书
     *
     * @param mchId 微信支付商户号
     * @param url 请求地址
     * @param data 请求参数
     * @return
     * @throws Exception
     */
    public static String doRefund(String mchId,String url, String data) throws Exception {
        /**
         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
         */
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        //P12文件目录 证书路径，linux下还是windows下的根路径
//        String filepath = "E:\\cert/apiclient_cert.p12";
        //服务器证书地址
        String filepath = "/home/file/cert/apiclient_cert.p12";
        FileInputStream instream = new FileInputStream(filepath);
        try {
            keyStore.load(instream, mchId.toCharArray());//这里写密码..默认是你的MCHID
        } finally {
            instream.close();
        }

        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();//这里也是写密码的
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
            HttpPost httpost = new HttpPost(url); // 设置响应头信息
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
                return jsonStr;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }

    /**
     * 交易流水号
     */
    public static String  generateTradeNo() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date();
        String str = simpleDateFormat.format(date);
        Random random = new Random();
        int rannum = (int) (random.nextDouble() *5);// 获取5位随机数
        return str + rannum;// 当前时间 + 系统5随机生成位数
    }


    /**
     * 商家付款到用户余额
     * @param orderCode 商户订单号
     * @param openid 用户的openid
     * @param totalFee 企业付款金额 (金额在0.3-100元之间）
     * @param desc 企业付款备注
     * @return
     */
    public static Map<String, Object> transfers(String orderCode, String openid, BigDecimal totalFee, String desc) {
        String appid = xcxAppId;
        String mch_id = xcxMchId;
        String apikey = appApiKey;

        //元转分
        String amount = totalFee.multiply(new BigDecimal(100)).toString();

        HashMap<String, Object> objMap = new HashMap<String, Object>();
        objMap.put("mch_appid", appid);    //商户账号appid
        objMap.put("mchid", mch_id);  //微信支付分配的商户号
        objMap.put("nonce_str", WeChatUtil.nonceString());  //随机字符串，长度要求在32位以内
        objMap.put("partner_trade_no", orderCode);  //商户订单号
        objMap.put("openid", openid);  //用户的openid
        objMap.put("check_name", "NO_CHECK");  //校验用户姓名选项(NO_CHECK：不校验真实姓名 FORCE_CHECK：强校验真实姓名)
        objMap.put("amount", amount);  //企业付款金额，单位为分
        objMap.put("desc", desc);  //企业付款备注，必填。注意：备注中的敏感词会被转成字符*

        log.info("传入参数：" + objMap.toString());

        SortedMap<Object, Object> packageParams = new TreeMap(objMap);
        packageParams.put("sign", WeChatUtil.createSign(packageParams, apikey));   //签名值
        String requestXML = WeChatUtil.getRequestXml(packageParams);
        String refundUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";

        //发起付款
        String respBody = null;
        try {
            respBody = doRefund(mch_id,refundUrl,requestXML);
        } catch (Exception e) {
            e.printStackTrace();
        }

        log.info("返回信息：" + respBody);

        Map<String, Object> respMap = null;
        if (StringUtils.isEmpty(respBody)) {
            ExceptionUtil.businessException("支付失败");
        }
        respMap = XmlUtil.xmlBody2map(respBody, "xml");

        String returnCode = (String) respMap.get("return_code");
        if ("SUCCESS".equals(returnCode)) {

            String result_code = (String) respMap.get("result_code");  //错误代码
            String errCode = (String) respMap.get("err_code");  //错误代码
            String errCodeDes = (String) respMap.get("err_code_des");   //错误代码描述
            String partnerTradeNo = (String) respMap.get("partner_trade_no");   //商户订单号
            String paymentNo = (String) respMap.get("payment_no");  //微信付款单号
            String paymentTime = (String) respMap.get("payment_time"); //付款成功时间

            HashMap<String, Object> returnMap = new HashMap();
            returnMap.put("resultCode", result_code);
            returnMap.put("errCode", errCode);
            returnMap.put("errCodeDes", errCodeDes);
            returnMap.put("partnerTradeNo", partnerTradeNo);
            returnMap.put("paymentNo", paymentNo);
            returnMap.put("paymentTime", paymentTime);

            return returnMap;
        } else {
            ExceptionUtil.businessException(respMap.get("return_msg").toString());
        }
        return null;
    }


}
